/**
 * app模块是平台的主模块
 * 本文件为最新版
 */

var FG;
if (!FG)
    FG = {};

FG.App = function(options) {
    var options_ = options || {};

    var this_ = this;

    this.modules = {};
    this.classes = {};

    this.settinger = this.registerModule(new DX.Settinger());

    DX.shout('app:pre_load_setting', this_);
    $.when(
        this.settinger.loadSysSetting(),
        this.settinger.loadUserSetting(),
        this.settinger.loadUserStatus()
    ).done(function() {
        this_._initBuiltinMods();
        this_.connectSignals();
        DX.shout('app:loaded', this_);
        setTimeout(function() {this_.toolPanel.toggleTab()}, 500);
        var poplayers = this_.poplayer.loadSysPopLayers();
        this_.poplayer.load(poplayers);
        if (poplayers.length > 0) {
            this_.poplayer.show();
        }
    });
};

FG.App.prototype._initBuiltinMods = function() {
    var this_ = this;
    this.toolModer = new FG.Moder();
    this.pageModer = new FG.Moder();
    this.pager = new FG.Pager({target: $('#main_layers')});   // 这个不太适合regitster, 因为不一定是单例.
    this.pager.addLayer('map', '<div id="map_panel"></div>');
    
    this.poplayer = this.registerModule(new FG.PopLayer({app: this, target: $('#poplayer')}));
    
    this.mapPanel = this.registerModule(new FG.MapPanel({app: this, target: 'map_panel'}));
    this.pageModer.registerMode('map', function() {this_.pager.toggleLayer('map')});
    
    this.toolPanel = new FG.Sidebar2ToolPanel({target: 'sidebar', map: this.mapPanel.map});

    this.userPanel = this.registerModule(new FG.UserPanel({app: this}));
    this.searchBox = this.registerModule(new DX.MapSearchBox({target: '#search', regionSearch: 'on'}));
    
    this.plotter = this.registerModule(new FG.Plotter({app: this}));
    this.registerModule(new FG.InitApp({app: this}));
    
    // projectPanel未来也应作为可选的模块.
    this.projectPanel = new FG.ProjectPanel({app: this});
    this.projectPanel.initialize();
    this.registerModule(this.projectPanel);
    
    this.projectCore = new FG.ProjectCore();  // projectCore中fetch的时机可能需要调整, 在ProjectMapConnection加载后再进行更合适.
    this.registerModule(this.projectCore);
    
    this.registerModule(new FG.ProjectMapConnection({app: this}));

    return this;
};

FG.App.prototype.registerModule = function(mod) {
    this.modules[mod.moduleInfo.name] = mod;
    if (!!mod.moduleInfo.exportList) {
        _.each(mod.moduleInfo.exportList, function(name) {
            FG[name] = _.bind(mod[name], mod);
        })
    }
    // if (mod.moduleInfo.paneMode === 'mono') {
    //     this.monoPanes.push(mod.moduleInfo.name);
    // }
    DX.shout('mod:registered', mod.moduleInfo.name);
    DX.debug(mod.moduleInfo.name);
    return mod;
};

FG.App.prototype.hasModule = function(modName) {
    return _.has(this.modules, modName);
};

FG.App.prototype.getModule = function(modName) {
    return this.modules[modName];
};

FG.App.prototype.registerClass = function(c, className) {
    var cn = !!className ? className : c.className;
    this.classes[cn] = c;
    return c;
};

FG.App.prototype.getClass = function(className) {
    return this.classes[className];
};

FG.App.prototype.connectSignals = function() {
    var this_ = this
};
